﻿
using Bridge.Shared.Models;
using Emails;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MimeKit;
using Notices;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Net.Pop3;
using Bridge.Shared.Extensions;
using MailKit.Search;

namespace Bridge.System.Application
{
    [RemoteService(IsEnabled =false)]
    public class SysEmailService : ApplicationService, ISysEmailService
    {
        private readonly IConfiguration _configuration;
        private SmtpSettings _smtpSettings;
        private readonly ILogger<SysEmailService> _logger;
  
        public SysEmailService(IConfiguration configuration, ILogger<SysEmailService> logger)
        {
            _configuration = configuration;
            _logger = logger;
            _smtpSettings = _configuration.GetSection("Smtp").Get<SmtpSettings>();
        }
        /// <summary>
        /// 发送邮件【多收件人】
        /// </summary>
        /// <param name="toEmails"></param>
        /// <param name="subject"></param>
        /// <param name="message"></param>
        /// <param name="attachments"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="EmailServiceException"></exception>
        public async Task<ResponseResult> SendMultipleEmailAsync(IEnumerable<string> toEmails, string subject, string message,
            IEnumerable<Emails.Attachment> attachments = null, CancellationToken cancellationToken = default)
        {
            if (toEmails == null || !toEmails.Any())
            {
                return ResponseResult.Fail("至少需要一个收件人");
            }
            if (string.IsNullOrEmpty(subject))
            {
                return ResponseResult.Fail("邮件主题不能为空");
            }
            var emailMessage = new MimeMessage();
            try
            {
                //发送方
                emailMessage.From.Add(new MailboxAddress(_smtpSettings.DisplayName, _smtpSettings.Username));
                //接收方
                emailMessage.To.AddRange(toEmails.Select(email => new MailboxAddress("", email)));
                //邮件主题
                emailMessage.Subject = subject;
                //构建邮件内容(内容文本＋附件)
                var bodyBuilder = new BodyBuilder { HtmlBody = message };
                if (attachments != null)
                {
                    foreach (var attachment in attachments)
                    {
                        byte[] fileContent;
                        using (var fileStream = new FileStream(attachment.FilePath,FileMode.Open, FileAccess.Read))
                        using (var memoryStream = new MemoryStream())
                        {
                            await fileStream.CopyToAsync(memoryStream, cancellationToken);
                            fileContent = memoryStream.ToArray();
                        }

                        //解析MIME类型
                        var (mainType, subType) = ParseMimeType(attachment.MimeType);

                        // 创建正确的ContentType（使用两个参数的构造函数）
                        var contentType = new MimeKit.ContentType(mainType, subType);
                        bodyBuilder.Attachments.Add(attachment.FileName, fileContent, contentType);
                    }
                }
                emailMessage.Body = bodyBuilder.ToMessageBody();
                using (var smtpClient = new SmtpClient())
                {
                    _logger.LogInformation("正在连接到SMTP服务器: {Host}:{Port}",
                    _smtpSettings.Host, _smtpSettings.Port);
                    await smtpClient.ConnectAsync(_smtpSettings.Host, _smtpSettings.Port, _smtpSettings.UseSsl, cancellationToken);

                    _logger.LogInformation("正在进行SMTP认证: {Username}", _smtpSettings.Username);
                    await smtpClient.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.Password, cancellationToken);

                    _logger.LogInformation("正在发送邮件至: {Recipients}", string.Join(",", toEmails));
                    await smtpClient.SendAsync(emailMessage, cancellationToken);

                    _logger.LogInformation("邮件发送成功，正在断开连接");
                    await smtpClient.DisconnectAsync(true, cancellationToken);
                }
            }
           
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送邮件失败 - {Message}", ex.Message);

                return ResponseResult.Fail("发送邮件失败: " + ex.Message);
            }

            return ResponseResult.Success();
        }

        /// <summary>
        /// 解析MIME类型为主要类型和子类型
        /// </summary>
        private (string mainType, string subType) ParseMimeType(string mimeType)
        {
            if (string.IsNullOrWhiteSpace(mimeType))
                return ("application", "octet-stream");

            var parts = mimeType.Split('/', 2);
            if (parts.Length != 2)
                return ("application", "octet-stream");

            return (parts[0], parts[1]);
        }



        public async  Task<ResponseResult> SendEmailAsync(string toEmail, string subject, string message, IEnumerable<Emails.Attachment> attachments = null, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(toEmail))
            {
                throw new ArgumentNullException("收件人邮箱不能为空", nameof(toEmail));
            }
          return  await SendMultipleEmailAsync(new List<string> { toEmail }, subject, message, attachments, cancellationToken);
        }


        public async Task<ResponseResult<List<EmailMessageOutput>>> GetInboxMessagesAsync(int maxCount = 50)
        {
            var messages = new List<EmailMessageOutput>();

            using (var client = new ImapClient())
            {
                try
                {
                    
                    // 连接服务器
                    await client.ConnectAsync(_smtpSettings.Host, 993,
                        SecureSocketOptions.SslOnConnect);

                    // 认证YGhfqz9ya73LYEtx
                    //PNkFbHU4W4nDrbJ5
                    await client.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.AuthenticateCode);

                    var clientImplementation = new ImapImplementation
                    {
                        Name = "Bridge",
                        Version = "1.0.0"
                    };
                    var serverImplementation = client.Identify(clientImplementation);

                    // 打开收件箱
                    var inbox = client.Inbox;
                    await inbox.OpenAsync(FolderAccess.ReadOnly);

                    Console.WriteLine($"总邮件数: {inbox.Count}, 未读邮件数: {inbox.Unread}");

                    // 计算要获取的邮件范围（最新的邮件）
                    var endIndex = inbox.Count - 1;
                    var startIndex = Math.Max(0, endIndex - maxCount + 1);

                    // 获取邮件摘要信息
                    var summaries = await inbox.FetchAsync(startIndex, endIndex,
                        MessageSummaryItems.UniqueId |
                        MessageSummaryItems.Envelope |
                        MessageSummaryItems.Flags |
                        MessageSummaryItems.BodyStructure);

                    foreach (var summary in summaries.Reverse()) // 从最新到最旧
                    {
                        var emailMessage = new EmailMessageOutput
                        {
                            Id = summary.UniqueId.ToString(),
                            Subject = summary.NormalizedSubject,
                            From = summary.Envelope.From.ToString(),
                            Date = summary.Envelope.Date?.DateTime ?? DateTime.Now,
                            IsRead = summary.Flags.Value.HasFlag(MessageFlags.Seen),
                            HasAttachments = summary.Attachments != null && summary.Attachments.Any()
                        };

                        messages.Add(emailMessage);
                    }

                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"获取邮件列表失败: {ex.Message}");
                }
            }

            return ResponseResult<List<EmailMessageOutput>>.Success("ok",messages);
        }

        public async Task<List<EmailMessageOutput>> GetInboxMessagesByPopAsync(int maxCount = 50)
        {
            var messages = new List<EmailMessageOutput>();

            using (var client = new Pop3Client())
            {
                try
                {
                    await client.ConnectAsync(_smtpSettings.Host, _smtpSettings.Port,
                        SecureSocketOptions.SslOnConnect);
                    await client.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.Password);

                    var messageCount = client.Count;
                    Console.WriteLine($"总邮件数: {messageCount}");

                    // 计算要获取的邮件范围（最新的邮件）
                    var startIndex = Math.Max(0, messageCount - maxCount);
                    var count = Math.Min(maxCount, messageCount);

                    for (int i = startIndex; i < messageCount; i++)
                    {
                        var message = await client.GetMessageAsync(i);

                        var emailMessage = new EmailMessageOutput
                        {
                            Id = i.ToString(),
                            Subject = message.Subject,
                            From = message.From.ToString(),
                            Date = message.Date.ToDateTime(),
                            TextBody = message.TextBody,
                            HtmlBody = message.HtmlBody
                        };

                        messages.Add(emailMessage);
                    }

                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"POP3接收邮件失败: {ex.Message}");
                }
            }

            return messages;
        }

        /// <summary>
        /// 获取完整邮件内容
        /// </summary>
        public async Task<EmailMessageOutput> GetFullMessageAsync(string uniqueId)
        {
            using (var client = new ImapClient())
            {
                try
                {
                    await client.ConnectAsync(_smtpSettings.Host, _smtpSettings.Port,
                        SecureSocketOptions.SslOnConnect);
                    await client.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.AuthenticateCode);

                    var inbox = client.Inbox;
                    await inbox.OpenAsync(FolderAccess.ReadOnly);

                    // 将字符串UniqueId转换回MailKit的UniqueId
                    if (UniqueId.TryParse(uniqueId, out var uid))
                    {
                        var message = await inbox.GetMessageAsync(uid);

                        return ConvertMimeMessageToEmailMessage(message, uid.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"获取邮件内容失败: {ex.Message}");
                }
            }

            return null;
        }

        /// <summary>
        /// 搜索未读邮件
        /// </summary>
        public async Task<List<EmailMessageOutput>> SearchUnreadMessagesAsync()
        {
            var messages = new List<EmailMessageOutput>();

            using (var client = new ImapClient())
            {
                try
                {
                    await client.ConnectAsync(_smtpSettings.Host, _smtpSettings.Port,
                        SecureSocketOptions.SslOnConnect);
                    await client.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.Password);

                    var inbox = client.Inbox;
                    await inbox.OpenAsync(FolderAccess.ReadOnly);

                    // 搜索未读邮件
                    var unreadUids = await inbox.SearchAsync(SearchQuery.NotSeen);

                    foreach (var uid in unreadUids)
                    {
                        var summary = await inbox.FetchAsync(new[] { uid },
                            MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags);

                        if (summary.Count > 0)
                        {
                            var emailMessage = new EmailMessageOutput
                            {
                                Id = uid.ToString(),
                                Subject = summary[0].NormalizedSubject,
                                From = summary[0].Envelope.From.ToString(),
                                Date = summary[0].Envelope.Date?.ToDateTime() ?? DateTime.Now,
                                IsRead = summary[0].Flags.Value.HasFlag(MessageFlags.Seen)
                            };

                            messages.Add(emailMessage);
                        }
                    }

                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"搜索未读邮件失败: {ex.Message}");
                }
            }

            return messages;
        }


        /// <summary>
        /// 下载邮件附件
        /// </summary>
        public async Task<List<EmailAttachment>> DownloadAttachmentsAsync(string uniqueId, string savePath = null)
        {
            var attachments = new List<EmailAttachment>();

            using (var client = new ImapClient())
            {
                try
                {
                    await client.ConnectAsync(_smtpSettings.Host, _smtpSettings.Port,
                        SecureSocketOptions.SslOnConnect);
                    await client.AuthenticateAsync(_smtpSettings.Username, _smtpSettings.Password);

                    var inbox = client.Inbox;
                    await inbox.OpenAsync(FolderAccess.ReadOnly);

                    if (UniqueId.TryParse(uniqueId, out var uid))
                    {
                        var message = await inbox.GetMessageAsync(uid);

                        foreach (var attachment in message.Attachments)
                        {
                            var fileName = attachment.ContentDisposition?.FileName ??
                                          attachment.ContentType.Name ??
                                          $"attachment_{Guid.NewGuid()}";

                            if (attachment is MimePart part)
                            {
                                using (var memoryStream = new MemoryStream())
                                {
                                    await part.Content.DecodeToAsync(memoryStream);
                                    var content = memoryStream.ToArray();

                                    var emailAttachment = new EmailAttachment
                                    {
                                        FileName = fileName,
                                        Content = content,
                                        ContentType = part.ContentType.MimeType
                                    };

                                    attachments.Add(emailAttachment);

                                    // 如果指定了保存路径，保存到文件
                                    if (!string.IsNullOrEmpty(savePath))
                                    {
                                        var fullPath = Path.Combine(savePath, fileName);
                                        await File.WriteAllBytesAsync(fullPath, content);
                                        Console.WriteLine($"附件已保存: {fullPath}");
                                    }
                                }
                            }
                        }
                    }

                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"下载附件失败: {ex.Message}");
                }
            }

            return attachments;
        }

        /// <summary>
        /// 将MimeMessage转换为自定义的EmailMessage
        /// </summary>
        private EmailMessageOutput ConvertMimeMessageToEmailMessage(MimeMessage mimeMessage, string uniqueId)
        {
            var emailMessage = new EmailMessageOutput
            {
                Id = uniqueId,
                Subject = mimeMessage.Subject,
                From = mimeMessage.From.ToString(),
                To = mimeMessage.To.ToString(),
                Date = mimeMessage.Date.ToDateTime(),
                TextBody = mimeMessage.TextBody,
                HtmlBody = mimeMessage.HtmlBody
            };
            return emailMessage;
        }
    }
}
